from typing import Tuple, Callable

import pygame

from game.container import CONSTANT, Variables
from game.data.assets.assetManager import load_image
from game.data.plot.plot import Dialog
from game.sound import ChannelManager
from game.sprites.base import Entity
from game.ui.widgets.image import ImageWidget
from game.ui.widgets.text import TextWidget
from game.world.coordinate import CoordinateType
from game.ui.menus import Menus


class Component:
    def __init__(self, ui= None):  # type:ignore
        self.ui = ui
        self.image_list = []
        self.text_list = []
        self.ui.component_list.append(self)

    def add_image(
            self,
            surface: pygame.Surface,
            center: CoordinateType,
            on_click_callbacks: Tuple[Callable[[], None], ...] = ()):

        image= ImageWidget(
                self.ui.display_surface,
                surface,
                center,
                self.ui.groups,
                on_click_callbacks
            )

        self.image_list.append(image)
        return image
    def add_text(
            self,

            center: CoordinateType,
            text: str,
            color: pygame.Color,
            background: pygame.Color | None = None,
            font=CONSTANT.APP.BUTTON_FONT,

            on_click_callbacks: Tuple[Callable[[], None], ...] = ()):

        text = TextWidget(
            self.ui.display_surface,
            center,
            self.ui.groups,
            text,
            color,
            background,
            font,
            on_click_callbacks)
        self.text_list.append(text)
        return text

    def undraw(self):
        self.ui.is_components_visible = False
        for image in self.image_list:
            image.undraw()
        for text in self.text_list:
            text.undraw()

    def draw(self):
        self.ui.is_components_visible = True
        for image in self.image_list:
            image.is_visible = True
        for text in self.text_list:
            text.is_visible = True

class ComponentsContainer:
    class SettingsComponent(Component):
        def __init__(self, ui):
            super().__init__(ui)
            self.add_text(
                (200, 200),
                "音量",
                pygame.Color(0, 0, 0),
                pygame.Color(255, 255, 255), )

            self.add_text((400, 200),
                          str(Variables.audio_volume),
                          pygame.Color(0, 0, 0),
                          pygame.Color(255, 255, 255), )
            volume_text = self.text_list[1]

            # decrease audio volume
            def __callback_volume_down():
                if Variables.audio_volume > 0:
                    Variables.audio_volume -= 1
                    ChannelManager.set_volume_all(Variables.audio_volume / 10)
                    volume_text.set_text(str(Variables.audio_volume))

            self.add_image(
                load_image("test/left_arrow.png"),
                (300, 200),
                on_click_callbacks=(__callback_volume_down,))

            # increase audio volume
            def __callback_volume_up():
                if Variables.audio_volume < 10:
                    Variables.audio_volume += 1
                    ChannelManager.set_volume_all(Variables.audio_volume / 10)
                    volume_text.set_text(str(Variables.audio_volume))

            self.add_image(
                load_image("test/right_arrow.png"),
                (500, 200),
                on_click_callbacks=(__callback_volume_up,)
            )

    class DialogComponent(Component):
        def __init__(self,
                     ui
                     ):
            super().__init__(ui)
            self.dialog = None
            self.has_choices = False
            
            img = load_image("test/DialogBox.png")
            
            self.dialog_box = self.add_image(
                pygame.transform.scale(
                    img,
                    (img.get_size()[0] * 4, img.get_size()[1] * 4),
                ),
                (640, 600))

            self.dialog_text = self.add_text(
                self.dialog_box.rect.center,
                '',
                pygame.Color(0, 0, 0),
            )

            self.name_text = self.add_text(
                (192, 506),
                # TODO:Can we pass topleft?
                '',
                pygame.color.Color(173,216,230),
            )

            def __callback_choice_1():
                self.choose(0)
            def __callback_choice_2():
                self.choose(1)

            def __callback_choice_3():
                self.choose(2)
            def __callback_choice_4():
                self.choose(3)
            self.choices_text = [
                self.add_text(
                (1150, 500),
                '',
                pygame.Color(0, 0, 0),
                on_click_callbacks=(__callback_choice_1,)
                ),
                self.add_text(
                    (1150, 450),
                    '',
                    pygame.Color(0, 0, 0),
                    on_click_callbacks=(__callback_choice_2,)
                ),
                self.add_text(
                    (1150, 400),
                    '',
                    pygame.Color(0, 0, 0),

                    on_click_callbacks=(__callback_choice_3,)
                ),
                self.add_text(
                    (1150, 350),
                    '',
                    pygame.Color(0, 0, 0),

                    on_click_callbacks=(__callback_choice_4,)
                )
            ]
            self.undraw()  # invisible for default

        def set_dialog(self):
            # self.undraw()
            self.name_text.set_text(self.dialog.get_current()[1].name)
            self.dialog_text.set_text(self.dialog.get_current()[1].sentence)

        def next_sentence(self):
            choices = self.dialog.get_next()
            self.set_dialog()
            if choices != 0:
                if choices is not None:
                    self.has_choices = True
                    for i in range(0, len(choices)):
                        self.choices_text[i].set_text(choices[i])
                        self.choices_text[i].set_visible()
            else:
                from game.event.eventManager import EventId, Eventbus
                Eventbus.triggerEvent(EventId.toggle_game_pause)
                self.undraw()
                self.has_choices = False
                Variables.in_dialog = False
                self.dialog.reset_dialog()

        def start_dialog(self, entity: Entity):
            from game.event.eventManager import EventId,Eventbus
            Eventbus.triggerEvent(EventId.toggle_game_pause)
            self.dialog = entity.dialog
            self.set_dialog()
            self.draw()
            if not self.has_choices:  # TODO:improve checking of choices
                for choice in self.choices_text:
                    choice.undraw()
            Variables.in_dialog = True




        def choose(self, id):
            # print('x')
            self.dialog.current_paragraph_index += 1
            self.dialog.get_current()
            self.dialog.current_paragraph.choice_index = id
            self.dialog.get_current()
            self.set_dialog()
            for choice in self.choices_text:
                choice.undraw()

    @classmethod
    def init(cls):
        cls.settings_settings_menu = cls.SettingsComponent(Menus.settings_menu)
        cls.settings_pause_menu = cls.SettingsComponent(Menus.pause_menu)
        cls.dialog = cls.DialogComponent(Menus.game_menu)
